<template>
	<div
		ref="rootRef"
		class="pf-ResizeObserver"
	>
		<template v-if="!hasObserver">
			<div
				ref="expandRef"
				class="pf-ResizeObserver_expand"
				@scroll.passive="emitEvent"
			><div/></div>
			<div
				ref="shrinkRef"
				class="pf-ResizeObserver_shrink"
				@scroll.passive="emitEvent"
			><div/></div>
		</template>
		<slot v-bind="containerSize"/>
	</div>
</template>

<script setup lang="ts">
import type {SizeObject} from '../../../type';
import {
	shallowRef,
} from 'vue';
import useScrollType from './useScrollType';
import useObserver from './useObserver';
/**
 * 监听大小组件
 * @author 唐国雄
 * @date 2022/8/31
 * 属性----------------------
 * :throttle	节流时间
 * 事件----------------------
 * @resize		大小改变
 * 插槽----------------------
 * #default
 * 方法----------------------
 * getSize()	获取当前大小
 */
if(typeof cache==='function'){
	cache=cache();
}
const {hasObserver}=cache;

const emit=defineEmits<{
	(e:'resize',size:SizeObject):void;
}>();
const props=withDefaults(defineProps<{
	throttle?:number|false;
}>(),{
	throttle:false,
});
//region 获取当前容器大小, 并发射resize事件
const containerSize=shallowRef<SizeObject>({
	width:0,
	height:0,
});
const rootRef=shallowRef<HTMLElement>(null);
const getSizeObject=() => {
	const {offsetWidth,offsetHeight}=rootRef.value;
	const {width,height}=containerSize.value;
	if(width!==offsetWidth||height!==offsetHeight){
		const newSize={
			width:offsetWidth,
			height:offsetHeight,
		};
		containerSize.value=newSize;
		emit('resize',newSize);
	}
};
//endregion
const expandRef=shallowRef<HTMLElement>(null);
const shrinkRef=shallowRef<HTMLElement>(null);
let emitEvent:() => void;
if(hasObserver){
	useObserver(rootRef,getSizeObject,props.throttle);
}else{
	emitEvent=useScrollType(expandRef,shrinkRef,getSizeObject,props.throttle);
}
//region 导出的内容
defineExpose({
	getSize():SizeObject{
		getSizeObject();
		return containerSize.value;
	},
});
//endregion
</script>

<script lang="ts">
//region 类型声明
interface Cache{
	hasObserver:boolean;
}
//endregion
//region 全局缓存
let cache:Cache|(() => Cache)=function(){
	return {
		hasObserver:typeof ResizeObserver!=='undefined',
	};
};
//endregion
export default {};
</script>